﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using SyringeControl.WinForms;
using System.ComponentModel;

namespace SyringeControl.ControlConfiguration.Events
{
    [TestFixture]
    public class Test_EventPropertyModel: IEventLogger
    {
        EventTabModel _model;
        IEventLoggingSettingsProvider _settingsProvider;
        IAdapterBuilder _builder;
        EventDescriptor _descr;

        [SetUp]
        public void SetUp()
        {
            _settingsProvider = new DefaultEventSettingsProvider();
            _builder = new GenericEventHandlerAdapterFactory();
            _model = new EventTabModel(new IEventLogger[]{this}, _builder, _settingsProvider);
            _descr = GetDescriptor();
            Assert.That(_builder.CanBuild(_descr.EventType));
        }

        [Test]
        public void PropertyModel_subscribes_loggers()
        {
            var settings = new EventLoggingSettings();
            _model.Component = this;
            _model.SetLogger(_descr, this);
            Assert.That(SomethingHappened.GetInvocationList().Length, Is.EqualTo(1));
            InvokeSomethingHappened("It happens");
            Assert.That(wasCalled);
        }

        [Test]
        public void PropertyModel_subscribes_loggers_according_to_settings()
        {
            var settings = _settingsProvider.GetSettingsForComponent(this);
            settings.SetLoggerType(_descr, this.GetType());
            _settingsProvider.SetSettingsForComponent(this, settings);
            _model.Component = this;
            InvokeSomethingHappened("It happens");
            Assert.That(wasCalled);
        }

        EventDescriptor GetDescriptor()
        {
            return TypeDescriptor.GetEvents(this).OfType<EventDescriptor>().Single(ev => ev.Name == "SomethingHappened");
        }

        public event EventHandler<EventArgs<string>> SomethingHappened;
        void InvokeSomethingHappened(string value)
        {
            var handler = SomethingHappened;
            if(handler != null)
                handler(this, new EventArgs<string>(value));
        }

        bool wasCalled;

        public void Handle(object sender, object args)
        {
            wasCalled = true;
        }

        [TearDown]
        public void TearDown()
        {
            wasCalled = false;
        }
    }
}
